Skip to content

feat(sc): rollout path — TQReplayBuffer, rollout_manager, _rollout_pump#3219

Merged
terrykong merged 11 commits into
mainfrom
yukih/sc-split-1
Jul 22, 2026
Merged

feat(sc): rollout path — TQReplayBuffer, rollout_manager, _rollout_pump#3219
terrykong merged 11 commits into
mainfrom
yukih/sc-split-1

Conversation

@yuki-97

@yuki-97 yuki-97 commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

Part 1/4 of the #2819 split. See #2819 (reference) or #3267 (4/4) for the full code and context.

#3219 (1/4) -> #3220 (2/4) -> #3266 (3/4) -> #3267 (4/4)

Summary

Rollout-side infrastructure for the SC (Single Controller) async-GRPO training path.

  • TQReplayBuffer (nemo_rl/algorithms/async_utils/replay_buffer.py): group-granular replay buffer with reserve/commit slot accounting; producer-side tensorization writes N training-shaped rows per prompt group. Replaces the WIP ReplayBufferNew.
  • RolloutManager.generate_and_push (nemo_rl/experience/rollout_manager.py): reserve a buffer slot, run one prompt rollout, commit with start/end weight versions. Also renames task_to_env → env_handles across both AsyncRolloutImpl and AsyncNemoGymRolloutImpl.
  • payload.py (nemo_rl/experience/payload.py): new pack_payload + record_to_train_batch helpers used by TQReplayBuffer.commit.
  • SingleControllerActor._rollout_pump: rewritten to dispatch prompts through the new RolloutManager, with per-weight-version quota (over_sampling=false) and exact target-step matching (force_in_order=true). New SingleControllerConfig fields over_sampling / force_in_order; actor __init__ gains rollout_manager / dataloader for driver-side wiring.
  • Tests: new test_tq_replay_buffer and test_rollout_pump; new test_rollout_manager replaces the old test_rollouts.py; TestReplayBufferNew removed from test_async_utils.

Note: _train_pump is left in its pre-refactor form in this PR (still uses dp_client.claim_meta + the old top-level StalenessSampler); PR#2 switches it to the new sampler.evict/select API. SC becomes end-to-end runnable only after PR#3 lands the driver-side setup and entrypoint.

Usage

min_groups_for_streaming_train (current called min_groups_per_batch, will be renamed in later PR)

min_groups_for_streaming_train over_sampling force_in_order
non-streaming (same as legacy) num_prompts_per_step False True
streaming 1 x (<= num_prompts_per_step) False True/False
streaming 2 x (<= num_prompts_per_step) True False

Known Missing Features (Tracked in #2625)

  1. Generation-level backpressure in the Single Controller: max_inflight_prompts -> max_inflight_rollouts
  2. Add over_sampling_ratio (>1) to avoid over sample to much and waste data.

@copy-pr-bot

copy-pr-bot Bot commented Jul 15, 2026

Copy link
Copy Markdown

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@yuki-97 yuki-97 added the CI:Lfast Runs a fast test suite and re-use nightly `main` container (but sync dependencies to PRs version) label Jul 15, 2026
@yuki-97

yuki-97 commented Jul 15, 2026

Copy link
Copy Markdown
Contributor Author

/ok to test a14ddff

@yuki-97

yuki-97 commented Jul 16, 2026

Copy link
Copy Markdown
Contributor Author

/ok to test c6ad118

@yuki-97
yuki-97 force-pushed the yukih/sc-split-1 branch 2 times, most recently from 02ca7f0 to 97ce826 Compare July 17, 2026 15:23
@yuki-97

yuki-97 commented Jul 17, 2026

Copy link
Copy Markdown
Contributor Author

/ok to test 97ce826

Comment thread nemo_rl/algorithms/single_controller.py
@yuki-97

yuki-97 commented Jul 18, 2026

Copy link
Copy Markdown
Contributor Author

/ok to test bf73365

@terrykong terrykong left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Team review of the rollout-path infrastructure (PR 1/4 of the #2819 split). The split is clean: parity coverage from test_rollouts.py moved 1:1 into test_rollout_manager.py (both *_matches_original guards survive), removed symbols (ReplayBufferNew, _rollout_done, _flush_incomplete_groups) have no dangling references, and the producer→consumer DataPlane contract (sample-id scheme + weight_version tag) stays compatible with the untouched _train_pump. Linters pass; 18 of the PR's unit tests were run locally on GPU (all pass), including test_async_rollout_manager_matches_original.

Findings were cross-checked against the rest of the stack (#3220 / #3266 / #3267) — items already resolved downstream (e.g. the dead max_rollout_prompts field, deleted in #3220; the finite-max_num_epochs termination gap, closed by #3220's dead-code removal plus #3266's max_num_steps ≤ max_num_epochs × len(dataloader) clamp) are intentionally NOT flagged inline. The remaining inline comments cover only what survives the full stack: a silent-failure/permit-leak path in the new fire-and-forget rollout dispatch, a missing @pytest.mark.vllm, stale excluded_unit_tests.sh deselect paths after the test move, an untested default dispatch branch, a likely-rebase-artifact pyrefly.toml removal, and a doc nit.

Non-blocking observations (no action needed in this PR):

  • RolloutManager's max_rollout_turns default changed from None (coerced to 999999 on the native path) to 1, and the coercion was removed. No production caller exists until PR#3, but a future native multi-turn caller that omits the arg now silently gets single-turn rollouts — worth keeping in mind for the PR#3 wiring.
  • The new config-validation raises in SingleControllerActor.__init__ live under # pragma: no cover; factoring them into a module-level helper would make them unit-testable (optional).

Generated by Claude Code

Comment thread nemo_rl/algorithms/single_controller.py Outdated
Comment thread tests/unit/single_controller/test_rollout_pump.py
Comment thread tests/unit/experience/test_rollout_manager.py
Comment thread tests/unit/single_controller/test_rollout_pump.py
Comment thread pyrefly.toml
Comment thread tests/unit/single_controller/test_rollout_pump.py Outdated
Comment thread nemo_rl/algorithms/single_controller.py
Comment thread tests/unit/experience/test_rollout_manager.py Outdated
@RayenTian

Copy link
Copy Markdown
Contributor

/ok to test efc7d31

@RayenTian

Copy link
Copy Markdown
Contributor

/ok to test c454acf

@RayenTian

Copy link
Copy Markdown
Contributor

/ok to test f929aa0

@RayenTian
RayenTian requested a review from terrykong July 21, 2026 09:40
yuki-97 and others added 9 commits July 21, 2026 20:07
Signed-off-by: Yuki Huang <yukih@nvidia.com>
…add target_step to _FakeBuffer.reserve

Signed-off-by: Yuki Huang <yukih@nvidia.com>
…shutdown path

Signed-off-by: Yuki Huang <yukih@nvidia.com>
…manager signatures

Signed-off-by: Yuki Huang <yukih@nvidia.com>
Signed-off-by: Yuki Huang <yukih@nvidia.com>
Signed-off-by: Yuki Huang <yukih@nvidia.com>
…force_in_order

Signed-off-by: Yuki Huang <yukih@nvidia.com>
Signed-off-by: ruit <ruit@nvidia.com>

@terrykong terrykong left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Follow-up review of the commits addressing the earlier round (bf73365f929aa0). The fixes hold up well under an adversarial concurrency pass: permit accounting is exactly-once on every interleaving we could construct (including cancel-before-start via task_started_event), run() now propagates rollout failures without orphaning tasks, and commit()'s rollback has no window against the train pump's claim path. The new tests genuinely exercise these paths, and the added @pytest.mark.vllm also fixes a latent lane bug (the test previously ran GPU work in the CPU-only Other shard). One low-severity note inline.

Generated by Claude Code

Comment thread nemo_rl/algorithms/async_utils/replay_buffer.py
@RayenTian

Copy link
Copy Markdown
Contributor

/ok to test 48184ad

@terrykong
terrykong enabled auto-merge (squash) July 22, 2026 06:22
terrykong
terrykong previously approved these changes Jul 22, 2026
Signed-off-by: ruit <ruit@nvidia.com>
@RayenTian

Copy link
Copy Markdown
Contributor

/ok to test 62a759a

@terrykong
terrykong merged commit 8ea1207 into main Jul 22, 2026
87 of 89 checks passed
@terrykong
terrykong deleted the yukih/sc-split-1 branch July 22, 2026 23:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CI:Lfast Runs a fast test suite and re-use nightly `main` container (but sync dependencies to PRs version)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants